using System;
using System.Collections.Generic;
using System.Text;
using CodePlex.Resourceful.Wadl;
using System.IO;
using CodePlex.Resourceful.Bookmarks.Model;

namespace CodePlex.Resourceful.Bookmarks.Controllers
{
    public class UsersController : BaseController
    {

        public UsersController(BookmarkEngine engine)
            : base(engine)
        {

        }


        // *** "user-controller" methods ***

        // pg 196-197
        public void CreateUser(IRepresentationContext context)
        {
            if (context.Request.MediaType != MediaType.ApplicationXml)
            {
                this.RenderStatus(context, HttpStatus.UnsupportedMediaType);
                return;
            }

            UserAccount user = UserAccount.FromXml(new StreamReader(context.Request.GetEntityStream()));

            context.Response.SetHeader(HttpHeader.Location, UserUrl(context, user.Name));

            if (this.Engine.FindUser(user.Name) != null)
            {
                this.RenderStatus(context, HttpStatus.Conflict);
                return;
            }

            // everything looks fine, do create
            this.Engine.Add(user);

            this.RenderStatus(context, HttpStatus.Created);



        }






        // pg 197-198
        public void UpdateUser(IRepresentationContext context)
        {



            if (context.Request.MediaType != MediaType.ApplicationXml)
            {
                this.RenderStatus(context, HttpStatus.UnsupportedMediaType);
                return;
            }



            string oldName = context.TemplateParameters["username"];


            UserAccount oldUser = this.Engine.FindUser(oldName);
            if (oldUser == null)
            {
                this.RenderStatus(context, HttpStatus.NotFound);
                return;
            }



            // better auth first
            if (!this.IsAuthorized(context, oldUser))
            {
                return;
            }



            UserAccount user = UserAccount.FromXml(new StreamReader(context.Request.GetEntityStream()));

            bool isChangingNames = user.Name != oldName;

            if (isChangingNames && this.Engine.FindUser(user.Name) != null)
            {
                this.RenderStatus(context, HttpStatus.Conflict);
                return;
            }

            // everything looks fine, do update


            this.Engine.Remove(oldUser);
            this.Engine.Add(user);


            if (isChangingNames)
            {
                context.Response.SetHeader(HttpHeader.Location, UserUrl(context, user.Name));

                this.RenderStatus(context, HttpStatus.MovedPermanently);

            }
            else
            {
                this.RenderStatus(context, HttpStatus.OK);
            }





        }









        // pg 198
        public void GetUser(IRepresentationContext context)
        {
            string username = context.TemplateParameters["username"];

            UserAccount user = this.Engine.FindUser(username);

            if (user == null)
            {
                this.RenderStatus(context, HttpStatus.NotFound);
                return;
            }

            if (context.Request.Accepts(MediaType.ApplicationExWwwFormUrlencoded))
            {
                context.Response.Render(
                 HttpStatus.OK,
                 MediaType.ApplicationExWwwFormUrlencoded,
                 user.ToFormUrlEncodedString());

            }
            else
            {

                context.Response.Render(
                    HttpStatus.OK,
                    MediaType.ApplicationXml,
                    Utils.ToString(user.ToXml));
            }



        }






        // pg 198
        public void DeleteUser(IRepresentationContext context)
        {
            string username = context.TemplateParameters["username"];

            UserAccount user = this.Engine.FindUser(username);

            if (user == null)
            {
                this.RenderStatus(context, HttpStatus.NotFound);
                return;
            }


            // better auth first
            if (!this.IsAuthorized(context, user))
            {
                return;
            }


            // delete

            this.Engine.Remove(user);

            this.RenderStatus(context, HttpStatus.OK);



        }





    }
}
